package se392.ateam2006.resourcemgmt.participant;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.OneToOne;

import se392.ateam2006.meetingmgmt.meeting.MeetingEntity;
import se392.ateam2006.user.UserEntity;

/**
 * Entity class to define the attributes and operations of a Participation (i.e. whether a user is attending a meeting)
 * This information can then be persisted into a database
 * @author Ateam (Matthew Bennett, Claire Melton, Shingai Manyiwa, John Adderley)
 * @version 25/03/07
 */
@Entity
public class ParticipationEntity implements Serializable {
    
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    
    @OneToOne
    private MeetingEntity meeting;
    @OneToOne
    private UserEntity userEntity;
    
    // 'active' is whether a user in an active participant of a meeting
    // i.e. do they actually have to be physically in the same room or
    // can they 'attend' via a video link, or whatever
    private boolean active = false;
    private boolean confirmed = false;
    private boolean attending = true;
    
    /**
     * Default constructor required because this is an entity class
     */
    public ParticipationEntity() {}
    
    /**
     * Create a new ParticipationEntity
     * @param user - the UserEntity to create the participation for
     * @param meeting - the MeetingEntity to create the participation for
     */ 
    public ParticipationEntity(UserEntity user, MeetingEntity meeting) {
        
        this(user, meeting, false, false);
    }
    
    /**
     * Creates a new instance of ParticipationEntity
     * Creates a participation relationship between a user and a meeting
     * @param user - the UserEntity to create the participation for
     * @param meeting - the MeetingEntity to create the participation for
     * @param state - boolean, is the user an active participant of the meeting?
     */
    public ParticipationEntity(UserEntity user, MeetingEntity meeting, boolean state) {
        
        this(user, meeting, state, false);
    }
    
    /**
     * Creates a new instance of ParticipationEntity
     * Creates a participation relationship between a user and a meeting
     * @param user - the UserEntity to create the participation for
     * @param meeting - the MeetingEntity to create the participation for
     * @param state - boolean, is the user an active participant of the meeting?
     * @param confirmed - boolean, has the user confirmed that they're going to attend the meeting?
     */
    public ParticipationEntity(UserEntity user, MeetingEntity meeting, boolean state, boolean confirmed) {
        
        this.userEntity = user;
        this.meeting = meeting;
        this.active = state;
        this.confirmed = confirmed;
    }
    
    /**
     * Get the user part of this participation
     * @return UserEntity - the user in the participation
     */
    public UserEntity getUserEntity() {
        return userEntity;
    }
    
    /**
     * Set the user part of this participation
     * @param user - the new UserEntity
     */
    public void setUserEntity(UserEntity user) {
        this.userEntity = user;
    }
    
    /**
     * Get whether the user is an active participant in the meeting
     * @return boolean - is the user an active participant?
     */
    public boolean isActive() {
        return active;
    }
    
    /**
     * Set whether the user is an active participant of the meeting
     * @param state - boolean, is the user an active participant?
     */
    public void setActive(boolean state) {
        this.active = state;
    }
    
    /**
     * Override the equals method...
     * @param otherItem - the object to compare to
     * @return boolean - are the objects equal?
     */
    public boolean equals(Object otherItem){
        if(otherItem instanceof ParticipationEntity) {
            ParticipationEntity other = (ParticipationEntity) otherItem;
            if(this.getUserEntity().getEmail().equals(other.getUserEntity().getEmail())&&
                    this.isActive() == other.isActive()){
                return true;
            }else{
                return false;
            }
        } else { return false; }
    }
    
    /**
     * Override the toString method...
     * @return String - string representation of the participation
     */
    public String toString() {
        return "ParicipationEntity: User=" + getUserEntity().getEmail() + 
                " , Meeting=" + getMeeting().getId();
    }
    
    /**
     * Get the meeting part of this participation
     * @return MeetingEntity - the meeting of the participation
     */
    public MeetingEntity getMeeting() {
        return meeting;
    }
    
    /**
     * Set the meeting part of the participation
     * @param meeting - MeetingEntity, the new meeting of the participation
     */
    public void setMeeting(MeetingEntity meeting) {
        this.meeting = meeting;
    }
    
    /**
     * Get whether a participation is confirmed
     * @return boolean - is the meeting confirmed?
     */
    public boolean isConfirmed() {
        return confirmed;
    }
    
    /**
     * Set whether the participation is confirmed
     * @param confirmed - boolean, the new state of the confirmed flag
     */
    public void setConfirmed(boolean confirmed) {
        this.confirmed = confirmed;
    }
    
    /**
     * Get whether the user is attending the meeting
     * @return boolean - is the user attending the meeting?
     */
    public boolean isAttending() {
        return attending;
    }
    
    /**
     * Set whether the user is attending the meeting
     * @param attending - boolean, the new value of the attending flag
     */
    public void setAttending(boolean attending) {
        this.attending = attending;
    }
    
    /**
     * Get the ID of this participation
     * @return long - the ID of the participation
     */
    public long getId() {
        return id;
    }
    
    /**
     * Set the ID of this participation
     * @param id - the new ID of this participation
     */
    public void setId(long id) {
        this.id = id;
    }
}
